//
//  POC_plugin.m
//  POC
//
//  Created by Leelucifer on 15/1/24.
//
//

#import "POC_plugin.h"
#import "Core.h"
#import "SGALines.h"
#import "Session.h"
#import "SGA.h"
#import "Error.h"
#import "VPN.h"
#import "Handle.h"
#import <CommonCrypto/CommonDigest.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>

#import <AdSupport/ASIdentifierManager.h>
#import "MainViewController.h"
#import "SimpleWebViewController2.h"




@implementation POC_plugin

CHANDLE Session = NULL;
NSTimer *heartTaskTimer = nil;
BOOL g_isTryRepeatSendHeart = NO;


-(void)changePwd:(CDVInvokedUrlCommand *)command
{
    NSArray* param=command.arguments;
    NSString* oldPwd=[[param objectAtIndex:0]objectForKey:@"oldPwd"];
    NSString* newPwd=[[param objectAtIndex:0]objectForKey:@"newPwd"];
    int result;
    if (Session==NULL) {
        result=-1;
    }
    result=CSessionChangePassword(Session, [oldPwd cStringUsingEncoding:NSUTF8StringEncoding],[newPwd cStringUsingEncoding:NSUTF8StringEncoding]);
    
    CDVPluginResult* pluginResult=nil;
    if(result==0){
        pluginResult=[CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
    }else if(result==-1){
        pluginResult=[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Session is null,please login again"];
    }else if(result==4){
        int errerCode=CSessionSGAError(Session);
        pluginResult=[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errerCode];
    }else{
        pluginResult=[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:result];
    }

    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

-(void)setVpn:(CDVInvokedUrlCommand *)command
{
    NSArray* param=command.arguments;
    NSString* ip=[[param objectAtIndex:0]objectForKey:@"ip"];
    NSString* passport=[[param objectAtIndex:0]objectForKey:@"passport"];
    NSString* password=[[param objectAtIndex:0]objectForKey:@"password"];
    
    int result=[self loginVpn:ip withParam:passport withParam:password];
    CDVPluginResult* pluginResult=nil;
    if (result==0) {
        pluginResult=[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"login fail"];
    }else if(result==1){
        pluginResult=[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"VPN init fail"];
    }else if(result==2){
        pluginResult=[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"VPN start fail"];
    }else if(result==3){
        NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
        NSString *app_build = [infoDictionary objectForKey:@"CFBundleVersion"];
        pluginResult=[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:app_build];
    }else{
        pluginResult=[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
    }
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

-(void)openPage:(CDVInvokedUrlCommand *)command
{
    NSArray* param=command.arguments;
    NSString *path=[[param objectAtIndex:0]objectForKey:@"path"];
    
    SimpleWebViewController2 *simpleWeb=[[SimpleWebViewController2 alloc]init];
    simpleWeb.path=path;
    [self.viewController presentModalViewController:simpleWeb animated:YES];
}

-(void)closePage:(CDVInvokedUrlCommand *)command
{
    [self.viewController dismissModalViewControllerAnimated:YES];
}

-(NSInteger)loginVpn:(NSString *)ip withParam:(NSString *)passport withParam:(NSString *)password
{
    //    获取最快的连接地址
    [self getTheFastLine];
    //   创建一个连接session
    CHANDLE  connectChandle = CSessionNew();
    
    //    初始化登录信息对象
    //    创建登录令牌和登录服务器
    CSESSION_LOGIN_TOKEN  LoginToken;
    CSESSION_LOGIN_SERVER LoginServer;
    memset(&LoginToken, 0, sizeof(LoginToken));
    memset(&LoginServer, 0, sizeof(LoginServer));
    //    设置登录服务器的参数
    LoginServer.Protocol = 0;
    strcpy(LoginServer.Address, [ip cStringUsingEncoding:NSUTF8StringEncoding]);
    //    设置登录令牌的参数,按实填写
    LoginToken.TokenSize = sizeof(LoginToken);
    LoginToken.Flags = SessionLoginTokenFlagUserPass;
    LoginToken.Username = (char *)[passport cStringUsingEncoding:NSUTF8StringEncoding];
    LoginToken.Password = (char *)[password cStringUsingEncoding:NSUTF8StringEncoding];
    char * hardw = "12344566";
    LoginToken.HardwareId = hardw;
    LoginToken.ClientType = SessionLoginClientTypeIPhone;
    LoginToken.ClientVersion = "3.4.6";
    LoginToken.NETWORKTYPE = "wifi";
    LoginToken.ISPCode = [[self queryCarrierIspCode] UTF8String];
    LoginToken.MCC = [[self queryCarrierCountryCode] UTF8String];
    LoginToken.PackageName = (char *)[[[NSBundle mainBundle] bundleIdentifier] UTF8String];
    
    //    登录,并返回状态码,可查询,0为成功
    CC_STATUS LoginStatus = CSessionLogin(connectChandle, &LoginServer, &LoginToken);
    NSLog(@"LoginStatus=%d",LoginStatus);
    
    //    登录成功后,开始获取sga多线路的信息
    if(LoginStatus == 0)
    {
        if(connectChandle == NULL)
        {
            return -1;
        }
        //        获取多线路的条数
        int iCount = SGALinesCount(connectChandle);
        NSLog(@"icount=%d",iCount);
        if (iCount > 0)
        {
            //            将线路的信息已ip:port,ip:port...形式存到本地,可以自己设定形式,取的时候也要对应
            SGA_LINE_INFO LineInfo;
            int Size = sizeof(SGA_LINE_INFO);
            NSMutableString *strAddr = [[[NSMutableString alloc] init] autorelease];
            
            for (int i = 0; i < iCount; i++)
            {
                memset(&LineInfo, 0, Size);
                //                获取多线路的详细信息
                CC_STATUS status = SGALineInfo(connectChandle, i, &LineInfo, &Size);
                if (0 == status)
                {
                    NSString *str = [NSString stringWithUTF8String:LineInfo.IP];
                    if ([str length] > 0)
                    {
                        if (i == iCount-1)
                        {
                            if (LineInfo.Port > 0)
                            {
                                [strAddr appendFormat:@"%@:%d", str, LineInfo.Port];
                            } else
                            {
                                [strAddr appendFormat:@"%@", str];
                            }
                        }
                        else
                        {
                            if (LineInfo.Port > 0)
                            {
                                [strAddr appendFormat:@"%@:%d,", str, LineInfo.Port];
                            }
                            else
                            {
                                [strAddr appendFormat:@"%@,", str];
                            }
                        }
                    }
                }
                
            }
            
            if ([strAddr length]>0)
            {
                NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
                NSString *strLocal = [userDefaults stringForKey:@"FASTLINE_SGAADDR"];
                //                如果本地存的多线路地址和这次请求的不一样,就把最新的保存下来
                if(![strAddr isEqualToString:strLocal])
                {
                    [userDefaults setObject:strAddr forKey:@"FASTLINE_SGAADDR"];
                    [userDefaults synchronize];
                }
            }
        }
    }
    else
    {
        return -1;
    }
    Session = connectChandle;
    
#pragma mark -VPN Test
    //    VPN示例.登录成功后初始化VPN,session为已经登录上的句柄
    CC_STATUS status = VPNInit(Session);
    if (status == 0)
    {
        VPNStart();
        return 3;
    }
    else
    {
        NSLog(@"ERROR VPN 初始化失败");
        return 1;
    }

    
    [self startSendHeart:[NSValue valueWithPointer:Session]];
    
    NSUserDefaults *userDefault=[NSUserDefaults standardUserDefaults];
    [userDefault setObject:ip forKey:@"ip"];
    [userDefault setObject:passport forKey:@"passport"];
    [userDefault setObject:password forKey:@"password"];
    return 3;
}


-(NSString *)queryCarrierIspCode
{
    CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init];
    
    CTCarrier *carrier = [info subscriberCellularProvider];
    if (nil == carrier) {
        [info release];
        return @"";
    }
    
    NSString *code = [carrier mobileNetworkCode];
    if (nil == code || 0 == [code length]) {
        [info release];
        return @"";
    }
    [info release];
    NSLog(@"%@-%@", NSStringFromSelector(_cmd), code);
    
    return code;
}
-(NSString *)queryCarrierCountryCode
{
    CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init];
    
    CTCarrier *carrier = [info subscriberCellularProvider];
    if (nil == carrier) {
        [info release];
        return @"";
    }
    
    NSString *code = [carrier mobileCountryCode];
    if (nil == code || 0 == [code length]) {
        [info release];
        return @"";
    }
    [info release];
    NSLog(@"%@-%@", NSStringFromSelector(_cmd), code);
    
    return code;
}
#pragma mark -getFastLine
-(NSString *)getTheFastLine
{
    NSString * strFastAddr = nil;
    NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
    NSString * strAddr = [userDefaults stringForKey:@"FASTLINE_SGAADDR"];
    if ([strAddr length]>0)
    {
        //        本地已经有上次保存的多线路地址,可以进行选路
        NSArray * array = [strAddr componentsSeparatedByString:@","];
        NSUInteger iCount = array.count;
        if (iCount > 0)
        {
            CSESSION_LOGIN_SERVER SGAServer[iCount];
            for (int i = 0; i < iCount; i++)
            {
                memset(&SGAServer[i], 0, sizeof(SGAServer[i]));
                NSString *strIp = [array objectAtIndex:i];
                strcpy(SGAServer[i].Address, [strIp UTF8String]);
                SGAServer[i].Protocol = 0;
            }
            //            多线路连接接口,返回最快线路的索引
            int index = SGAMultiLine(SGAServer, iCount);
            if (index >= 0) {
                const char *addr = SGAServer[index].Address;
                strFastAddr = [NSString stringWithUTF8String:addr];
            }
        }
    }
    
    if ([strFastAddr length]>0) {
        [userDefaults stringForKey:@"FASTLINE_FASTADDR"];
    }
    [userDefaults synchronize];
    NSLog(@"strFastAddr = %@",strFastAddr);
    return strFastAddr;
}

- (void)startSendHeart:(NSValue *)sender
{
    if (sender)
    {
        NSLog(@"heartThread start");
        g_isTryRepeatSendHeart = NO;//复原重发心跳状态值
        heartTaskTimer = [NSTimer scheduledTimerWithTimeInterval:60.0f target:self selector:@selector(heartSendTimer:) userInfo:sender repeats:YES];
    }
}

- (void)stopSendHeart
{
    if (heartTaskTimer)
    {
        NSLog(@"heartThread stop");
        [heartTaskTimer invalidate];
        heartTaskTimer = nil;
    }
}

- (void)heartSendTimer:(NSTimer *)timer
{
    NSLog(@"heartThread send");
    NSValue *value = timer.userInfo;
    if (nil != value)
    {
        if (NO == g_isTryRepeatSendHeart)
        {
            [self performSelectorInBackground:@selector(sendHeartMethod:) withObject:value];
        }
        else
        {
            NSLog(@"正在重发心跳");
        }
    }
}

-(void)sender{
    CSessionLogout(Session);
    [self stopSendHeart];
    NSURL* startURL = [NSURL URLWithString:@"setting.html"];
    NSString* startFilePath = [self.commandDelegate pathForResource:[startURL path]];
    NSString *appURL = [NSURL fileURLWithPath:startFilePath];
    NSURLRequest* appReq = [NSURLRequest requestWithURL:appURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0];
    [self.webView loadRequest:appReq];
}

- (void)sendHeartMethod:(NSValue *)sender
{
   
    CHANDLE handle = [sender pointerValue];
    if (NULL == handle)
    {
        return;
    }
    
    CC_STATUS status = CSessionSendHeartbeat(handle);
    
    if (ERR_SUCCESS != status)
    {
        if (ERR_SGACALL == status)
        {
            SGA_ERROR_CODE sgaError = CSessionSGAError(handle);
            if (SGA_ERROR_OK != sgaError)
            {
                NSLog(@"%s", CSGAErrorString(sgaError));
            }
            else
            {
                NSLog(@"%s", CCStatusToErrorString(status));
            }
            
            // todo 需要注销会话等释放操作
            NSLog(@"后台错误，需要注销释放资源，重新登录");
            //[self sender];
        }
        else
        {
            if (ERR_INVALID_SESSION == status)
            {
                NSLog(@"%s", CCStatusToErrorString(status));
                
                // todo 需要注销会话等释放操作
                NSLog(@"会话已经无效，需要注销释放资源，重新登录");
                [self sender];
            }
            else
            {
                g_isTryRepeatSendHeart = YES;//开始尝试重发心跳
                
                BOOL isTrySuccess = NO;
                for (int i = 0; i < INT_MAX; i++)
                {
                    if (NULL == Session)//判断是否被注销，此为demo，条件不一定准确
                    {
                        NSLog(@"已经被注销，不需要重新发送");
                        //[self sender];
                        break;
                    }
                    
                    NSLog(@"立即重发心跳%d次", i+1);
                    CC_STATUS res = CSessionSendHeartbeat(handle);
                    if (ERR_SUCCESS == res)
                    {
                        isTrySuccess = YES;
                        NSLog(@"重发心跳%d次成功", i+1);
                        break;
                    }
                    else
                    {
                        if (ERR_INVALID_SESSION == status)
                        {
                            NSLog(@"会话已经无效,不需重发");
                            //[self sender];
                            break;
                        }
                        else
                        {
                            //间隔5s重发一次
                            [NSThread sleepForTimeInterval:5.0f];
                        }
                    }
                }
                
                g_isTryRepeatSendHeart = NO;//重发心跳结束
            }
        }
    }
    
    
    
}

@end
